﻿using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Windows;
using WpfApp.Update;
using WpfApp.ViewModels;

namespace WpfApp
{
    public class MatRecApp : Application
    {
        public MatRecApp()
        {
            this.Resources.MergedDictionaries.Add(new ResourceDictionary
            {
                Source = new Uri("pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml")
            });
            this.Resources.MergedDictionaries.Add(new ResourceDictionary
            {
                Source = new Uri("pack://application:,,,/HandyControl;component/Themes/Theme.xaml")
            });
        }

        [STAThread]
        public static void Main()
        {
            var app = new MatRecApp();
            app.Run();
        }

        private IHost _appHost = null!;

        public const string AppId = "92eb35bd-8e6a-429f-a3ed-6e850ffc94da";

        private static Mutex? InstanceMutex = null;

#pragma warning disable CS0414 // 添加只读修饰符
        private Task _updateTask = null!;
#pragma warning restore CS0414 // 添加只读修饰符

        private static bool AlreadyRun()
        {
            if (Mutex.TryOpenExisting(AppId, out var mutex))
            {
                return true;
            }

            InstanceMutex = new Mutex(true, AppId);

            return false;
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            if (AlreadyRun())
            {
                MessageBox.Show("极片分级程序已经运行！", "用户提示");
                this.Shutdown();
                return;
            }

            Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
#if RELEASE
            .MinimumLevel.Information()
#else
            .MinimumLevel.Debug()
#endif
            .WriteTo.File(
                  path: "logs/app/log-.txt", // 注意路径和文件名格式
                  rollingInterval: RollingInterval.Day, // 按天滚动
                  rollOnFileSizeLimit: true, // 在文件大小达到限制时也滚动
                  retainedFileCountLimit: 7, // 保留最近7天的日志文件
                  outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}",
                  fileSizeLimitBytes: 10 * 1024 * 1024 // 每个文件最大10MB
            )
            .CreateLogger();

            Log.Logger.Information("应用程序启动");

            this.DispatcherUnhandledException += (s, e) =>
            {
                Log.Logger.Error(e.Exception, "软件错误");
                MessageBox.Show(e.Exception.Message, "错误提示", MessageBoxButton.OK, MessageBoxImage.Error);
                e.Handled = true; // 处理异常
                // 关闭应用程序
                this.Shutdown();
            };

            AppDomain.CurrentDomain.UnhandledException += (s, e) =>
            {
                if (e.ExceptionObject is Exception ex)
                {
                    Log.Logger.Error(ex, "软件错误");
                    MessageBox.Show(ex.Message, "错误提示", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                this.Shutdown();
            };

            var builder = Host.CreateApplicationBuilder(new HostApplicationBuilderSettings()
            {
#if RELEASE
                EnvironmentName = Environments.Production
#else
                EnvironmentName = Environments.Development
#endif
            });

            builder.Services.AddHttpClient();

            // 配置使用 Autofac 依赖注入
            builder.ConfigureContainer(new AutofacServiceProviderFactory(), builder =>
            {
                builder.RegisterModule<WpfAppModule>();
            });

            // 注册 automapper
            builder.Services.AddAutoMapper(config =>
            {
                new AutoMapperConfig(config);
            });

            // 注册日志服务
            builder.Services.AddSerilog();

            _appHost = builder.Build();
            _appHost.Start();

            LoadCert();

            this.MainWindow = _appHost.Services.GetRequiredService<MainWindow>();
            this.MainWindow.Show();

            try
            {
                var path = Path.Combine(AppContext.BaseDirectory, Assembly.GetEntryAssembly()!.GetName().Name + ".exe");
                WindowsApi.SetAutoStart($"MatRec[{AppId}]", path);
                var vm = MainWindow.DataContext as MainWindowViewModel;
                vm?.LogMessage("已设置开机自启动！", Microsoft.Extensions.Logging.LogLevel.Information);
            }
            catch (Exception ex)
            {
                Log.Logger.Error(ex, "设置自启动失败!");
                MessageBox.Show("设置开机自启动失败！");
            }

            var updateService = _appHost.Services.GetRequiredService<UpdateService>();

            Task.Run(async () =>
            {
                await updateService.StartMonitoringAsync();
            });
        }

        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);
            // Finally, once just before the application exits...
            Log.CloseAndFlush();
        }

        private static void LoadCert()
        {
            // 打开受信任的根证书颁发机构存储  
            using (X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
            {
                // 打开存储区以进行写操作  
                store.Open(OpenFlags.ReadWrite);

                var existingCert = store.Certificates.FirstOrDefault(item => item.Issuer == "O=FlyingEye, L=NONE, S=NONE, C=CH");

                if (existingCert == null)
                {
                    var file = Path.Combine(AppContext.BaseDirectory, "Assets/certificate.pfx");
                    var cert = new X509Certificate2(file, "1q2w3e*");

                    // 将证书添加到存储区  
                    store.Add(cert);
                }

                // 关闭存储区  
                store.Close();
            };
        }
    }
}
